#ifndef SYNTAXANALYSER_H
#define SYNTAXANALYSER_H

#include <QObject>
#include <QList>
#include <QPair>
#include <QMap>

#include "lexicalanalyser.h"
#include "syntaxtreenode.h"
#include "scopetemplate.h"
#include "procedure.h"
#include "variable.h"

class SyntaxAnalyser : public QObject
{
	Q_OBJECT

public:
	SyntaxAnalyser(QObject *parent = 0);
	SyntaxAnalyser(QString &code, QObject *parent = 0);
	~SyntaxAnalyser();

	void setSource(QString &source);

	SyntaxTreeNode* tree();
	QList<Procedure> procedureList();

	Procedure* isDeclared(Procedure p);

	bool addProcedure(Procedure p);	
	bool addVariable(Symbol type, Symbol id, Symbol val = Symbol());

	bool exists(Procedure p);

	bool equalTypes(VariableType t1, Symbol t2);

	VariableType typeOf(QString id);

	SyntaxTreeNode* executionPartNode();

	SyntaxTreeNode* procedure(Procedure p);
	ScopeTemplate loadScope(Procedure p);
	ScopeTemplate loadGlobalScope();
	ScopeTemplate loadMainScope();

	bool Program();	 

private:

	bool DeclarationPart();
	bool ExecutionPart();
	bool DefinitionPart();
	bool VarDeclaration();
	bool ProcedureDeclaration();
	bool Block();
	QPair<bool , VariableType> /*bool*/  Const();
	bool Statments();
	bool Assigment(Symbol id);
	QPair<bool , VariableType> /*bool*/  Expression();
	QPair<bool , VariableType> /*bool*/  SimpleExp();
	
	QPair<bool , VariableType> /*bool*/  MinorFactor();
	QPair<bool , VariableType> /*bool*/  PriorFactor();
	QPair<bool , VariableType> /*bool*/ RelOp();
	QPair<bool , VariableType> /*bool*/ MinorOp();
	QPair<bool , VariableType> /*bool*/ PriorOp();
	QPair<bool , VariableType> /*bool*/  ProcedureCall(Symbol id);
	bool GetVarCall();
	bool PrintVarCall();
	bool IfStatment();
	bool WhileStatment();
	//QPair<bool , VariableType> /*bool*/  Value();

	bool accept(SymbolType type, QString txt, SyntaxTreeNode* curr);
	VariableType type(QString s);

private:
	SyntaxTreeNode* root;			// rozbity na czesci kod programu (ExecutionPart)

	// obsluga procedur
	QList<Procedure> procedures;	// rozbite na czesci procedury i info o nich (arg, zwracany typ)	
	
	// obsluga zmiennych
	QMap<qint32, ScopeTemplate > vars;
	QMap<Procedure, qint32>	proc_id;	// id procedury do kontroli typow (procedura ma swoje id scopa)
	qint32 curr_scope;
	qint32 max_scope;

	// drzewo rozbioru programu
	SyntaxTreeNode* curr_treenode;	
	Symbol			curr_symbol;

	// modul analizy leksykalnej
	LexicalAnalyser* lexical;	
};

#endif // SYNTAXANALYSER_H